package com.dsprun.dspai.services;


import com.dsprun.dspai.dto.ActionRequest;
import com.dsprun.dspai.model.CodeGenerationResponse;
import com.dsprun.dspai.model.DocumentResponse;
import com.dsprun.dspai.model.Person;
import com.dsprun.dspai.model.Sentiment;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentParser;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.document.parser.TextDocumentParser;
import dev.langchain4j.data.document.parser.apache.poi.ApachePoiDocumentParser;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;

import javax.script.ScriptEngineManager;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * AI服务实现类，提供各种AI功能
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AiService {

    // 注入的AI模型
    private final ChatLanguageModel deepseekChatModel;              // DeepSeek聊天模型
    private final StreamingChatLanguageModel deepseekStreamingChatModel; // DeepSeek流式聊天模型
    private final EmbeddingModel embeddingModel;                   // 嵌入模型

    // 内存存储结构
    private final Map<String, ChatMemory> chatMemories = new ConcurrentHashMap<>(); // 会话记忆存储
    private final Map<String, DocumentStore> documentStores = new ConcurrentHashMap<>(); // 文档存储

    /**
     * 文档存储接口，封装文档相关信息
     */
    private interface DocumentStore {
        EmbeddingStore<TextSegment> getEmbeddingStore(); // 获取嵌入存储
        String getDocumentName();                      // 获取文档名称
        Date getUploadDate();                          // 获取上传日期
    }

    /**
     * 文档存储实现类
     */
    private record DocumentStoreImpl(EmbeddingStore<TextSegment> embeddingStore,
                                     String documentName,
                                     Date uploadDate) implements DocumentStore {
        @Override
        public EmbeddingStore<TextSegment> getEmbeddingStore() {
            return embeddingStore;
        }

        @Override
        public String getDocumentName() {
            return documentName;
        }

        @Override
        public Date getUploadDate() {
            return uploadDate;
        }
    }



    /**
     * 简单聊天
     * @param message 用户消息
     * @return AI生成的响应
     */
    public String chat(String message) {
        log.debug("Processing chat request with message: {}", message);
        return deepseekChatModel.chat(message);
    }

    /**
     * 流式聊天
     * @param message 用户消息
     * @return 响应流
     */
//    public Flux<String> chatStream(String message) {
//        log.debug("Processing streaming chat request with message: {}", message);
//        return Flux.create(sink -> {
//            deepseekStreamingChatModel.chat(message, (StreamingChatResponseHandler) new FluxResponseHandler(sink));
//        });
//    }
    public Flux<String> chatStream(String message) {
        log.debug("Processing streaming chat request with message: {}", message);
        return Flux.create(sink -> {
            StreamingChatResponseHandler handler = new FluxResponseHandler(sink);
            deepseekStreamingChatModel.chat(message, handler);
        });
    }

    /**
     * 带记忆的聊天
     * @param message 用户消息
     * @param conversationId 会话ID
     * @return AI生成的响应
     */
    public String chatWithMemory(String message, String conversationId) {
        ChatMemory chatMemory = chatMemories.computeIfAbsent(
                conversationId,
                id -> MessageWindowChatMemory.withMaxMessages(10)
        );
        ChatMessage chatMessage = new dev.langchain4j.data.message.UserMessage(message);
        chatMemory.add(chatMessage);

        // 修改这里：使用 ChatResponse 而不是 Response<AiMessage>
        ChatResponse response = deepseekChatModel.chat(chatMemory.messages());

        // 假设 ChatResponse 有 getMessage() 方法获取 AI 回复
        String aiMessage = response.aiMessage().text();
        chatMemory.add(AiMessage.aiMessage(aiMessage));

        return aiMessage;
    }

    /**
     * 带记忆的流式聊天
     * @param message
     * @param conversationId
     * @return
     */
    public Flux<String> chatWithMemoryStream(String message, String conversationId) {
        // 1. 获取或创建对话记忆
        ChatMemory chatMemory = chatMemories.computeIfAbsent(
                conversationId,
                id -> MessageWindowChatMemory.withMaxMessages(10)
        );

        // 2. 添加用户消息到记忆
        chatMemory.add(UserMessage.from(message));

        List<ChatMessage> chatlist = chatMemory.messages();

        return Flux.create(sink -> {
            StreamingChatResponseHandler handler = new FluxResponseHandler(sink);
            deepseekStreamingChatModel.chat(chatlist, handler);
        });
    }

    /**
     * 清理过期对话记忆
     * @param timeoutMinutes 超时时间(分钟)
     */
    public void cleanupExpiredMemories(int timeoutMinutes) {
        chatMemories.entrySet().removeIf(entry -> {
            // 实现记忆过期检查逻辑
            // 可以根据最后访问时间判断
            return isMemoryExpired(entry.getValue(), timeoutMinutes);
        });
    }

    private boolean isMemoryExpired(ChatMemory memory, int timeoutMinutes) {
        // 实际实现可根据需要记录最后访问时间
        return false;
    }
    /**
     * 从文本中提取个人信息
     * @param text 包含个人信息的文本
     * @return 提取出的个人信息对象
     */
    public Person extractInfo(String text) {
        log.debug("Extracting information from text: {}", text);
        InformationExtractor extractor = AiServices.create(InformationExtractor.class, deepseekChatModel);
        return extractor.extractPersonFrom(text);
    }

    /**
     * 分析文本情感
     * @param text 待分析文本
     * @return 情感分析结果
     */
    public Sentiment analyzeSentiment(String text) {
        log.debug("Analyzing sentiment for text: {}", text);
        SentimentAnalyzer analyzer = AiServices.create(SentimentAnalyzer.class, deepseekChatModel);
        return analyzer.analyzeSentimentOf(text);
    }

    /**
     * 生成文本摘要
     * @param text 原文
     * @param maxLength 摘要最大长度
     * @return 生成的摘要
     */
    public String generateSummary(String text, int maxLength) {
        log.debug("Generating summary for text with max length: {}", maxLength);
        SummaryGenerator generator = AiServices.create(SummaryGenerator.class, deepseekChatModel);
        return generator.generateSummary(text, maxLength);
    }

    /**
     * 加载并处理文档
     * @param file 上传的文档文件
     * @return 文档信息响应
     */
    @SneakyThrows
    public DocumentResponse loadDocument(MultipartFile file) {
        log.info("Loading document: {}", file.getOriginalFilename());

        String documentId = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();

        // 使用文件内容直接作为输入流，无需保存临时文件
        try (InputStream inputStream = file.getInputStream()) {
            DocumentParser parser = getDocumentParser(originalFilename);
            Document document = parser.parse(inputStream);  // 直接使用输入流

            EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
            EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                    .embeddingModel(embeddingModel)
                    .embeddingStore(embeddingStore)
                    .build();

            ingestor.ingest(document);

            DocumentStore documentStore = new DocumentStoreImpl(
                    embeddingStore,
                    originalFilename,
                    new Date()
            );

            documentStores.put(documentId, documentStore);

            return new DocumentResponse(
                    documentId,
                    originalFilename,
                    new Date(),
                    file.getSize(),
                    getFileExtension(originalFilename)
            );
        }
    }

    // 辅助方法：获取文件扩展名
    private String getFileExtension(String filename) {
        return filename != null ?
                filename.substring(filename.lastIndexOf(".") + 1) :
                "";
    }

    /**
     * 根据文件名获取合适的文档解析器
     * @param filename 文件名
     * @return 文档解析器
     */
    private DocumentParser getDocumentParser(String filename) {
        if (filename == null) {
            return new TextDocumentParser();
        }

        String lowerCaseFilename = filename.toLowerCase();
        if (lowerCaseFilename.endsWith(".pdf")) {
            return new ApachePdfBoxDocumentParser();  // PDF解析器
        } else if (lowerCaseFilename.endsWith(".docx") || lowerCaseFilename.endsWith(".doc")) {
            return new ApachePoiDocumentParser();      // Word文档解析器
        } else {
            return new TextDocumentParser();          // 纯文本解析器
        }
    }

    /**
     * 文档问答
     * @param question 问题
     * @param documentId 文档ID
     * @return AI生成的回答
     */
    public String askDocument(String question, String documentId) {
        log.debug("Asking question '{}' about document {}", question, documentId);

        // 获取文档存储
        DocumentStore documentStore = documentStores.get(documentId);
        if (documentStore == null) {
            throw new IllegalArgumentException("Document not found");
        }

        // 创建内容检索器
        ContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(documentStore.getEmbeddingStore())
                .embeddingModel(embeddingModel)
                .maxResults(2)  // 最多返回2个相关片段
                .build();

        // 创建文档助手
        DocumentAssistant assistant = AiServices.builder(DocumentAssistant.class)
                .chatLanguageModel(deepseekChatModel)
                .contentRetriever(retriever)
                .build();

        return assistant.answer(question);
    }

    /**
     * 获取所有已加载文档列表
     * @return 文档信息列表
     */
    public List<DocumentResponse> listDocuments() {
        log.debug("Listing all loaded documents");
        return documentStores.entrySet().stream()
                .map(entry -> new DocumentResponse(
                        entry.getKey(),
                        entry.getValue().getDocumentName(),
                        entry.getValue().getUploadDate()))
                .collect(Collectors.toList());
    }

    /**
     * 文本翻译
     * @param text 待翻译文本
     * @param targetLanguage 目标语言
     * @return 翻译结果
     */
    public String translate(String text, String targetLanguage) {
        log.debug("Translating text to {}: {}", targetLanguage, text);
        Translator translator = AiServices.create(Translator.class, deepseekChatModel);
        return translator.translate(text, targetLanguage,"ZH");
    }

    /**
     * 代码生成
     * @param description 功能描述
     * @param language 目标语言
     * @return 生成的代码
     */
    public CodeGenerationResponse generateCode(
            String description,
            String language,
            String style,
            boolean includeComments,
            List<String> libraries,
            int complexityLevel,
            boolean includeTests) {

        // 1. 构建提示消息
        dev.langchain4j.data.message.UserMessage  userMessage = dev.langchain4j.data.message.UserMessage.from(buildCodePrompt(
                description, language, style, includeComments,
                libraries, complexityLevel, includeTests
        ));

        // 2. 调用模型（新版API）
        ChatResponse response = deepseekChatModel.chat(userMessage);
        String generatedContent = response.aiMessage().text();

        // 3. 解析响应
        CodeParseResult parseResult = parseGeneratedCode(generatedContent, language);

        return new CodeGenerationResponse(
                parseResult.getCode(),
                language,
                parseResult.getExplanation(),
                includeTests ? parseResult.getTestCode() : null,
                0
        );
    }
    private String buildCodePrompt(
            String description,
            String language,
            String style,
            boolean includeComments,
            List<String> libraries,
            int complexityLevel,
            boolean includeTests) {

        return String.format("""
        请生成%s代码，要求：
        - 功能：%s
        - 风格：%s
        - 语言版本：最新稳定版
        - 注释：%s
        - 使用库：%s
        - 复杂度：%d/5
        - 单元测试：%s
        
        返回格式：
        ```%s
        // 代码实现
        ```
        
        说明：
        // 实现思路解释
        """,
                language,
                description,
                style,
                includeComments ? "需要详细注释" : "无需注释",
                libraries != null ? String.join(",", libraries) : "无",
                complexityLevel,
                includeTests ? "需要" : "不需要",
                language.toLowerCase()
        );
    }

    /**
     * 解析AI生成的代码响应
     * @param response AI模型的原始响应内容
     * @param language 目标编程语言
     * @return 解析后的代码、解释和测试代码
     */
    private CodeParseResult parseGeneratedCode(String response, String language) {
        CodeParseResult result = new CodeParseResult();

        // 1. 处理包含Markdown代码块的响应
        if (response.contains("```")) {
            parseMarkdownResponse(response, language, result);
        }
        // 2. 处理纯代码+注释的响应
        else {
            parsePlainResponse(response, result);
        }

        // 3. 后处理验证
        validateParsedResult(result, language, response);
        return result;
    }

    /**
     * 解析Markdown格式的响应（带代码块）
     */
    private void parseMarkdownResponse(String response, String language, CodeParseResult result) {
        // 示例响应格式：
        // ```java
        // public class Main { ... }
        // ```
        // 说明：这是一个Java类...

        String codeBlockPattern = "```" + language + "?(.*?)```";
        Pattern pattern = Pattern.compile(codeBlockPattern, Pattern.DOTALL);
        Matcher matcher = pattern.matcher(response);

        // 提取主代码块
        if (matcher.find()) {
            result.setCode(matcher.group(1).trim());
        }

        // 提取测试代码块（如果有）
        String testBlockPattern = "```(?:test|" + language + "-test)\\s*(.*?)```";
        pattern = Pattern.compile(testBlockPattern, Pattern.DOTALL);
        matcher = pattern.matcher(response);
        if (matcher.find()) {
            result.setTestCode(matcher.group(1).trim());
        }

        // 提取说明部分（代码块之后的内容）
        String[] parts = response.split("```");
        if (parts.length > 2) {
            String explanation = parts[parts.length - 1]
                    .replaceAll("(?i)说明?[:：]?", "")
                    .trim();
            result.setExplanation(explanation);
        }
    }

    /**
     * 解析纯文本格式的响应
     */
    private void parsePlainResponse(String response, CodeParseResult result) {
        // 尝试分离代码和注释
        String[] lines = response.split("\n");
        StringBuilder code = new StringBuilder();
        StringBuilder explanation = new StringBuilder();

        for (String line : lines) {
            if (line.trim().startsWith("//") || line.trim().startsWith("#")) {
                explanation.append(line.replaceFirst("^[#/]+", "").trim())
                        .append("\n");
            } else {
                code.append(line).append("\n");
            }
        }

        result.setCode(code.toString().trim());
        result.setExplanation(explanation.toString().trim());
    }

    /**
     * 验证解析结果的有效性
     */
    private void validateParsedResult(CodeParseResult result,
                                      String language,
                                      String originalResponse) {
        // 1. 确保至少解析出代码
        if (result.getCode() == null || result.getCode().isEmpty()) {
            result.setCode("// 未能解析出有效代码\n" +
                    "// 原始响应：\n" +
                    originalResponse.substring(0, Math.min(200, originalResponse.length())));
        }

        // 2. 添加语言标识注释
        if (!result.getCode().startsWith("//") && !result.getCode().startsWith("#")) {
            String header = String.format(
                    language.equals("python") ?
                            "# 语言: %s\n# 生成时间: %s\n\n" :
                            "// 语言: %s\n// 生成时间: %s\n\n",
                    language,
                    LocalDateTime.now()
            );
            result.setCode(header + result.getCode());
        }

        // 3. 自动生成基础说明（如果没有）
        if ((result.getExplanation() == null || result.getExplanation().isEmpty())
                && !result.getCode().isEmpty()) {
            result.setExplanation(String.format(
                    "自动生成说明：\n" +
                            "- 语言: %s\n" +
                            "- 主要功能: 根据描述生成的代码实现\n" +
                            "- 建议: 请根据实际需求进行测试和调整",
                    language
            ));
        }
    }

    /**
     * 临时存储解析结果的内部类
     */
    @Data
    private static class CodeParseResult {
        private String code;         // 主代码内容
        private String explanation;  // 实现说明
        private String testCode;     // 单元测试代码

        public CodeParseResult() {
            this.code = "";
            this.explanation = "";
            this.testCode = "";
        }
    }

    /**
     * 智能体调度器
     */
    public interface AgentDispatcher {
        /**
         * 根据自然语言描述执行对应操作
         * @param command 自然语言指令
         * @return 执行结果
         */
        @dev.langchain4j.service.UserMessage("""
        根据用户指令选择最合适的操作，只返回以下JSON格式：
        {
            "action": "search|calculate|translate|analyze",
            "parameters": {
                // 各action专用参数
            }
        }
        
        可用操作：
        - search: 当用户需要查询信息时使用
        - calculate: 当需要进行数学计算时使用
        - translate: 当需要语言翻译时使用
        - analyze: 当需要情感分析时使用
        当前指令：{{it}}
        """)
        String dispatchAction(String command);
    }
    // ========== AI服务接口定义 ==========

    /**
     * 信息提取接口
     */
    interface InformationExtractor {

        @dev.langchain4j.service.UserMessage("将以下文本提取个人信息：{{text}}")
        Person extractPersonFrom(String text);
    }

    /**
     * 情感分析接口
     */
    interface SentimentAnalyzer {
        Sentiment analyzeSentimentOf(String text);
    }

    /**
     * 摘要生成接口
     */
    interface SummaryGenerator {
        @dev.langchain4j.service.UserMessage("生成以下文本的摘要，长度不超过{{maxLength}}个字符：{{text}}")
        String generateSummary(String text, int maxLength);
    }

    /**
     * 文档助手接口
     */
    interface DocumentAssistant {
        String answer(String question);
    }

    /**
     * 翻译接口
     */
    interface Translator {
        @dev.langchain4j.service.UserMessage("将以下{{sourceLanguage}}文本翻译成{{targetLanguage}}：{{text}}")
        String translate(
                @V("text") String text,
                @V("targetLanguage") String targetLanguage,
                @V("sourceLanguage") String sourceLanguage
        );
    }

    /**
     * 代码生成接口
     */
    interface CodeGenerator {
        @dev.langchain4j.service.UserMessage("Generate {{language}} code for: {{description}}")
        String generateCode(String description, String language);
    }

    // ========== 内部类 ==========

    /**
     * 流式响应处理器，用于将 LangChain4j 的流式响应桥接到 Reactor 的 Flux
     */
    private static class FluxResponseHandler implements StreamingChatResponseHandler {
        private final FluxSink<String> sink;
        private static final String END_MARKER = "[END]";  // 终止标记

        FluxResponseHandler(FluxSink<String> sink) {
            this.sink = sink;
        }

        @Override
        public void onPartialResponse(String token) {
            if (token != null && !token.isEmpty()) {
                sink.next(token);  // 推送每个 token
            }
        }

        @Override
        public void onCompleteResponse(ChatResponse chatResponse) {
            // 1. 可选：检查是否有未发送的尾部内容
            if (chatResponse != null && chatResponse.aiMessage() != null) {
                String fullResponse = chatResponse.aiMessage().text();
                if (fullResponse != null && !fullResponse.isEmpty()) {
                    sink.next(fullResponse);
                }
            }

            // 2. 发送终止标记
            sink.next(END_MARKER);

            // 3. 完成流
            sink.complete();
        }

        @Override
        public void onError(Throwable error) {
            sink.error(error);
        }
    }
}
